package data;

import java.util.LinkedList;
import java.util.List;

import model.SearchQuery;

import org.apache.jena.atlas.lib.StrUtils;

import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFormatter;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;

public class Remote {
	/**
	 * Queries the label for a property from DBPedia
	 * 
	 * @param resource
	 *            the id of the city to lookup
	 * @param language
	 *            the language for the label (Example: "en" =English)
	 * @return result of the label query
	 */
	public String queryCityLabel(String resource, String language) {
		String request = StrUtils.strjoinNL(
				"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>",
				"SELECT ?l", "WHERE {", "<" + resource + "> rdfs:label ?l.",
				"FILTER (lang(?l) = \"" + language + "\")", "}", "LIMIT 1");

		Query query = QueryFactory.create(request);
		QueryExecution qexec = QueryExecutionFactory.sparqlService(
				"http://dbpedia.org/sparql", query);

		ResultSet remoteDataset = null;

		String label = "";

		remoteDataset = qexec.execSelect();
		List<QuerySolution> solutions = ResultSetFormatter
				.toList(remoteDataset);
		if (solutions.size() > 0) {
			label = ((QuerySolution) solutions.get(0)).get("l").toString();
			label = label.substring(0, label.indexOf("@"));
		}
		return label;
	}

	/**
	 * Queries the required elements for a city from DBPedia
	 * 
	 * @param resource
	 *            the id of the city to lookup
	 * @param language
	 *            the language of the needed data (Example: "en" =English)
	 * @return Result of the Query encapsulated in the Querysolution
	 */
	public QuerySolution queryCity(String city, String language) {
		String request = StrUtils
				.strjoinNL(
						"PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>",
						"SELECT ?a ?latitude ?longitude ?photo ?jan ?feb ?mar ?apr ?may ?jun ?jul ?aug ?sep ?oct ?nov ?dec",
						"WHERE {",
						"<"
								+ city
								+ "> <http://dbpedia.org/ontology/abstract> ?a.",
						"<" + city + "> geo:lat ?latitude.",
						"<" + city + "> geo:long ?longitude.",
						"<"
								+ city
								+ "> <http://dbpedia.org/property/hasPhotoCollection> ?photo.",
						"OPTIONAL {<"
								+ city
								+ "> <http://dbpedia.org/property/janMeanC> ?jan.",
						"<"
								+ city
								+ "> <http://dbpedia.org/property/febMeanC> ?feb.",
						"<"
								+ city
								+ "> <http://dbpedia.org/property/marMeanC> ?mar.",
						"<"
								+ city
								+ "> <http://dbpedia.org/property/aprMeanC> ?apr.",
						"<"
								+ city
								+ "> <http://dbpedia.org/property/mayMeanC> ?may.",
						"<"
								+ city
								+ "> <http://dbpedia.org/property/junMeanC> ?jun.",
						"<"
								+ city
								+ "> <http://dbpedia.org/property/julMeanC> ?jul.",
						"<"
								+ city
								+ "> <http://dbpedia.org/property/augMeanC> ?aug.",
						"<"
								+ city
								+ "> <http://dbpedia.org/property/sepMeanC> ?sep.",
						"<"
								+ city
								+ "> <http://dbpedia.org/property/octMeanC> ?oct.",
						"<"
								+ city
								+ "> <http://dbpedia.org/property/novMeanC> ?nov.",
						"<"
								+ city
								+ "> <http://dbpedia.org/property/decMeanC> ?dec.}",
						"FILTER (lang(?a) = \"" + language + "\")", "}",
						"LIMIT 1");

		Query query = QueryFactory.create(request);
		QueryExecution qexec = QueryExecutionFactory.sparqlService(
				"http://dbpedia.org/sparql", query);

		ResultSet remoteDataset = null;

		remoteDataset = qexec.execSelect();
		List<QuerySolution> solutions = ResultSetFormatter
				.toList(remoteDataset);

		return solutions.get(0);
	}

	/**
	 * Extracts the links to the actual pictures from the page that is saved in
	 * DBPedia
	 * 
	 * @param photoURL
	 *            The link to the picture page, where the picture links are
	 *            stored in RDF format
	 * @return Links to the actual pictures
	 */
	public List<String> queryCityPhotos(String photoURL) {
		// list to hold the photo links
		List<String> photoURLList = new LinkedList<String>();
		if (photoURL == null) {
			return null;
		}
		Model m = ModelFactory.createDefaultModel();
		try {
			m.read(photoURL);
			// search the photo URL inside the photo RDF page
			QueryExecution qExec = QueryExecutionFactory.create(
					"PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n"
							+ "SELECT DISTINCT ?d where{?s ?p ?o."
							+ "?s foaf:depiction ?d}", m);
			ResultSet rs = qExec.execSelect();
			List<QuerySolution> photos = ResultSetFormatter.toList(rs);
			for (QuerySolution s : photos) {
				// replace marker to get pictures with better resolution
				photoURLList.add(s.get("d").toString()
						.replace("_m.jpg", ".jpg"));
			}
		} catch (Exception e) {
			System.out.println(e);
		}
		return photoURLList;
	}
	
	public Model getCitiesByTemperature(SearchQuery citylist) {
		String meanProp = "<http://dbpedia.org/property/"
				+ citylist.getMonth().substring(0, 3).toLowerCase() + "MeanC>";

		String request = StrUtils.strjoinNL(
				"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>",
				"CONSTRUCT { ?city " + meanProp + " ?meanTemp } WHERE {",
				"?city " + meanProp + " ?meanTemp.",
				"?city <http://dbpedia.org/ontology/country> ?country.",
				"FILTER (?meanTemp " + citylist.getGreaterThan() + " "
						+ citylist.getTemp() + " )" + "}");

		Query query = QueryFactory.create(request);
		QueryExecution qexec = QueryExecutionFactory.sparqlService(
				"http://dbpedia.org/sparql", query);

		Model results = ModelFactory.createDefaultModel();
		results = qexec.execConstruct();
		
		return results;
	}
}
